package cn.edu.zut.salarymanagesystem.activities;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

import com.alibaba.fastjson.JSON;
import com.haibin.calendarview.Calendar;
import com.haibin.calendarview.CalendarLayout;
import com.haibin.calendarview.CalendarView;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

import cn.edu.zut.salarymanagesystem.EnglishWeekBar;
import cn.edu.zut.salarymanagesystem.R;
import cn.edu.zut.salarymanagesystem.base.BaseActivity;
import cn.edu.zut.salarymanagesystem.bean.pojo.Attendence;
import cn.edu.zut.salarymanagesystem.bean.vo.AttendanceResult;
import cn.edu.zut.salarymanagesystem.bean.vo.OperateResult;
import cn.edu.zut.salarymanagesystem.config.Storage;
import cn.edu.zut.salarymanagesystem.utils.AlertBuilder;
import cn.edu.zut.salarymanagesystem.utils.Browser;
import okhttp3.OkHttpClient;
import okhttp3.Request;

public class CalendarViewActivity extends BaseActivity implements
        CalendarView.OnCalendarSelectListener,
        CalendarView.OnCalendarLongClickListener,
        CalendarView.OnMonthChangeListener,
        CalendarView.OnYearChangeListener,
        CalendarView.OnWeekChangeListener,
        CalendarView.OnViewChangeListener,
        CalendarView.OnCalendarInterceptListener,
        CalendarView.OnYearViewChangeListener,
        DialogInterface.OnClickListener,
        View.OnClickListener {

    TextView mTextMonthDay;

    TextView mTextYear;

    TextView mTextLunar;

    TextView mTextCurrentDay;

    CalendarView mCalendarView;

    RelativeLayout mRelativeTool;
    private int mYear;
    CalendarLayout mCalendarLayout;

    private AttendanceResult attendanceResult;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_calen_view;
    }

    @SuppressLint("SetTextI18n")
    @Override
    protected void initView() {
        bindMethond();
        setStatusBarDarkMode();
        mTextMonthDay = findViewById(R.id.tv_month_day);
        mTextYear = findViewById(R.id.tv_year);
        mTextLunar = findViewById(R.id.tv_lunar);

        mRelativeTool = findViewById(R.id.rl_tool);
        mCalendarView = findViewById(R.id.calendarView);

        //mCalendarView.setRange(2018, 7, 1, 2019, 4, 28);
        mTextCurrentDay = findViewById(R.id.tv_current_day);
        mTextMonthDay.setOnClickListener(v -> {
            if (!mCalendarLayout.isExpand()) {
                mCalendarLayout.expand();
                return;
            }
            mCalendarView.showYearSelectLayout(mYear);
            mTextLunar.setVisibility(View.GONE);
            mTextYear.setVisibility(View.GONE);
            mTextMonthDay.setText(String.valueOf(mYear));
        });
        mCalendarLayout = findViewById(R.id.calendarLayout);
        mCalendarView.setOnYearChangeListener(this);
        mCalendarView.setOnCalendarSelectListener(this);
        mCalendarView.setOnMonthChangeListener(this);
        mCalendarView.setOnCalendarLongClickListener(this, true);
        mCalendarView.setOnWeekChangeListener(this);
        mCalendarView.setOnYearViewChangeListener(this);

        //设置日期拦截事件，仅适用单选模式，当前无效
        mCalendarView.setOnCalendarInterceptListener(this);
        mCalendarView.setOnViewChangeListener(this);
        mTextYear.setText(String.valueOf(mCalendarView.getCurYear()));
        mYear = mCalendarView.getCurYear();
        mTextMonthDay.setText(mCalendarView.getCurMonth() + "月" + mCalendarView.getCurDay() + "日");
        mTextLunar.setText("今日");
        mTextCurrentDay.setText(String.valueOf(mCalendarView.getCurDay()));
    }

    private void bindMethond() {
        findViewById(R.id.btn_back).setOnClickListener(v -> finish());
        findViewById(R.id.btn_next_month).setOnClickListener(v -> mCalendarView.scrollToNext());
        findViewById(R.id.btn_previous_month).setOnClickListener(v -> mCalendarView.scrollToPre());
    }

    @SuppressLint("SetTextI18n")
    @RequiresApi(api = Build.VERSION_CODES.O)
    @SuppressWarnings("unused")
    @Override
    protected void initData() {
        fillData(mCalendarView.getCurYear(), mCalendarView.getCurMonth());
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case 0:
                mCalendarView.setWeekStarWithSun();
                break;
            case 1:
                mCalendarView.setWeekStarWithMon();
                break;
            case 2:
                mCalendarView.setWeekStarWithSat();
                break;
            case 3:
                if (mCalendarView.isSingleSelectMode()) {
                    mCalendarView.setSelectDefaultMode();
                } else {
                    mCalendarView.setSelectSingleMode();
                }
                break;
            case 4:
                mCalendarView.setWeekBar(EnglishWeekBar.class);
                break;
            case 5:
                mCalendarView.setAllMode();
                break;
            case 6:
                mCalendarView.setOnlyCurrentMode();
                break;
            case 7:
                mCalendarView.setFixMode();
                break;
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        }
    }

    private Calendar getSchemeCalendar(int year, int month, int day, int color, String text) {
        Calendar calendar = new Calendar();
        calendar.setYear(year);
        calendar.setMonth(month);
        calendar.setDay(day);
        calendar.setSchemeColor(color);//如果单独标记颜色、则会使用这个颜色
        calendar.setScheme(text);
        return calendar;
    }


    @Override
    public void onCalendarOutOfRange(Calendar calendar) {
        Toast.makeText(this, String.format("%s : OutOfRange", calendar), Toast.LENGTH_SHORT).show();
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onCalendarSelect(Calendar calendar, boolean isClick) {
        // 循环本月的签到列表，如果存在相同的 day 就表示这天有记录
        if (isClick && this.attendanceResult != null && this.attendanceResult.getList() != null) {
            for (Attendence attendence : attendanceResult.getList()) {
                if (calendar.getDay() == attendence.getTime().getDate()) {
                    AlertDialog dialog = AlertBuilder.getDayDialog(this, attendence, calendar);
                    dialog.show();
                    break;
                }
            }
        }
        mTextLunar.setVisibility(View.VISIBLE);
        mTextYear.setVisibility(View.VISIBLE);
        mTextMonthDay.setText(calendar.getMonth() + "月" + calendar.getDay() + "日");
        mTextYear.setText(String.valueOf(calendar.getYear()));
        mTextLunar.setText(calendar.getLunar());
        mYear = calendar.getYear();
    }

    @Override
    public void onCalendarLongClickOutOfRange(Calendar calendar) {
        Toast.makeText(this, String.format("%s : LongClickOutOfRange", calendar), Toast.LENGTH_SHORT).show();
    }

    // 长按回调
    @Override
    public void onCalendarLongClick(Calendar calendar) {
    }

    // 月份改变
    @SuppressLint("SetTextI18n")
    @Override
    public void onMonthChange(int year, int month) {
        Calendar calendar = mCalendarView.getSelectedCalendar();
        mTextLunar.setVisibility(View.VISIBLE);
        mTextYear.setVisibility(View.VISIBLE);
        mTextMonthDay.setText(calendar.getMonth() + "月" + calendar.getDay() + "日");
        mTextYear.setText(String.valueOf(calendar.getYear()));
        mTextLunar.setText(calendar.getLunar());
        mYear = calendar.getYear();
        fillData(year, month);
    }

    @Override
    public void onViewChange(boolean isMonthView) {
        Log.e("onViewChange", "  ---  " + (isMonthView ? "月视图" : "周视图"));
    }


    @Override
    public void onWeekChange(List<Calendar> weekCalendars) {
        for (Calendar calendar : weekCalendars) {
            Log.e("onWeekChange", calendar.toString());
        }
    }

    @Override
    public void onYearViewChange(boolean isClose) {
        Log.e("onYearViewChange", "年视图 -- " + (isClose ? "关闭" : "打开"));
    }

    /**
     * 屏蔽某些不可点击的日期，可根据自己的业务自行修改
     *
     * @param calendar calendar
     * @return 是否屏蔽某些不可点击的日期，MonthView和WeekView有类似的API可调用
     */
    @Override
    public boolean onCalendarIntercept(Calendar calendar) {
        Log.e("onCalendarIntercept", calendar.toString());
        int day = calendar.getDay();
        return day == 1 || day == 3 || day == 6 || day == 11 || day == 12 || day == 15 || day == 20 || day == 26;
    }

    @Override
    public void onCalendarInterceptClick(Calendar calendar, boolean isClick) {
        Toast.makeText(this, calendar.toString() + "拦截不可点击", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onYearChange(int year) {
        mTextMonthDay.setText(String.valueOf(year));
        Log.e("onYearChange", " 年份变化 " + year);
    }

    private void fillData(int years, int months) {
        // 获取考勤信息，阻塞式...
        FutureTask<AttendanceResult> task = new FutureTask<>(() -> {
            OkHttpClient client = Browser.getClient();
            String queryString = "" + years + "-" + months;
            Request request = new Request.Builder().url(Storage.url + "/attendance/getDated?uid=" + Storage.currentUser.getUid() + "&date=" + queryString).build();
            String json = client.newCall(request).execute().body().string();
            OperateResult operateResult = JSON.parseObject(json, OperateResult.class);
            Object data = operateResult.getData();
            if (data != null) {
                return JSON.parseObject(JSON.toJSONString(data), AttendanceResult.class);
            } else {
                Log.e("d8g", "获取到勤结果失败！");
                return null;
            }
        });
        new Thread(task).start();
        while (!task.isDone()) {
            //...
        }
        AttendanceResult result = null;
        try {
            result = task.get();
        } catch (ExecutionException | InterruptedException e) {
            Log.e("d8g", "获取考勤信息失败！");
        }
        this.attendanceResult = result;
        ((TextView) findViewById(R.id.tv_attendance_info)).setText("您在" + months + "月到勤了" + result.getTotalDays() + "天，工作了" + result.getTotalOvertimeHours() + "个小时");
        Map<String, Calendar> map = new HashMap<>();
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        for (Attendence attendence : result.getList()) {
            String flag = attendence.getFlag() == 0 ? "全" : attendence.getFlag() == 1 ? "半" : "时";
            map.put(sdf.format(attendence.getTime()), getSchemeCalendar(attendence.getTime().getYear(), attendence.getTime().getMonth(), attendence.getTime().getDay(), 0xFFbc13f0, flag));
        }
        mCalendarView.setSchemeDate(map);
    }
}
